/**
 * 
 */
package jp.tkym.labs.util.beankey;

import jp.tkym.labs.util.prop.PropertyResolver;
import jp.tkym.labs.util.prop.PropertyResolverProvider;


public class BeanKeyGenerator<B>{
	private PropertyResolver<B> propertyResolver;
	private String[] properties;
	private static final String STRING_SEPARATOR = "\'";
	
	public BeanKeyGenerator(Class<B> cls, String...properties){
		propertyResolver = PropertyResolverProvider.getInstance().get(cls);
		this.properties = properties;
	}
	
	public BeanKey generate(B bean){
		Object[] values = new Object[properties.length];
		for(int i=0; i<properties.length; i++){
			values[i] = propertyResolver.get(bean, properties[i]);
		}
		return new BeanKey(values);
	}
	
	public B bean(BeanKey key){
		B bean = propertyResolver.createInstance();
		for(int i=0; i<properties.length; i++){
			propertyResolver.set(bean, properties[i], key.values()[i]);
		}
		return bean;
	}
	
	public String encode(Object... values){
		StringBuilder sb = new StringBuilder();
		if(properties.length != values.length){
			String msg = 
				"values length "+ values.length +" is unsupported , " +
				"because properties length is " + properties.length;
			throw new IllegalArgumentException(msg);
		}
		for(int i=0; i<properties.length; i++){
//			Class<?> type = propertyResolver.getTypeOf(properties[i]);
//			String str = type.cast(values[i]).toString();
			String str = values[i].toString();
			sb.append(str);
			sb.append(STRING_SEPARATOR);
		}
		return sb.toString();
	}
	
	public String encode(BeanKey key){
		return encode(key.values());
	}
	
	public BeanKey decode(String str){
		String[] arrays = str.split(STRING_SEPARATOR);
		if(arrays.length != properties.length){
			String msg = "Unsupport String KeyValue [" + str + "]";
			throw new IllegalArgumentException(msg);
		}
		Object[] values = new Object[properties.length];
		for(int i=0; i<properties.length; i++){
			String strValue = arrays[i];
			Class<?> type = propertyResolver.getTypeOf(properties[i]);
			values[i] = decordValue(type, strValue);
		}
		return new BeanKey(values);
	}
	
	Object decordValue(Class<?> cls, String s){
		if(cls.equals(String.class))	return s;
		if(cls.equals(Integer.class) || cls.equals(int.class))	
			return Integer.parseInt(s);
		if(cls.equals(Long.class) || cls.equals(long.class))	
			return Long.parseLong(s);
		if(cls.equals(Byte.class) || cls.equals(byte.class))
			return Byte.parseByte(s);
		if(cls.equals(Float.class) || cls.equals(float.class))
			return Float.parseFloat(s);
		if(cls.equals(Double.class) || cls.equals(double.class))
			return Double.parseDouble(s);
		if(cls.equals(Short.class) || cls.equals(short.class))
			return Short.parseShort(s);
		throw new IllegalArgumentException(cls.getName()+" is unsupport Class type");
	}
}